<script setup lang="ts">
import { ref, onMounted, onUnmounted, nextTick, reactive } from 'vue';
import { debounce } from './util';

interface FormState {
  originWidth: string | number;
  originHeight: string | number;
  ready: boolean;
  width: string | number;
  height: string | number;
}
const props = withDefaults(
  defineProps<{
    optionsWidth: string | number; // 页面宽度
    optionsHeight: string | number; // 页面高度
  }>(),
  {
    optionsHeight: 0,
    optionsWidth: 0
  }
);

const state = reactive<FormState>({
  originWidth: 0, //视口宽度
  originHeight: 0, //视口高度
  ready: false,
  width: 0,
  height: 0
});
const refName = ref();
let dom: any , observer: any ;
//初始化
const initSize = () => {
  return new Promise((resolve?: any) => {
    nextTick(() => {
      //获取refs
      dom = document.getElementById('controlCabin-container');
      // 获取组件是否传入宽高
      // 传入 获取大屏真实尺寸
      if (props.optionsWidth && props.optionsHeight) {
        state.width = props.optionsWidth;
        state.height = props.optionsHeight;
      } else {
        // 否则传给refs的宽高
        state.width = dom.value.clientWidth;
        state.height = dom.value.clientHeight;
      }
      // 获取画布的尺寸
      if (!state.originWidth || state.originHeight) {
        state.originWidth = window.screen.width;
        state.originHeight = window.screen.height;
      }
      resolve();
    });
  });
};
//更新dom宽高
const updateSize = () => {
  if (state.width && state.height) {
    dom.style.width = `${state.width}px`;
    dom.style.height = `${state.height}px`;
  } else {
    dom.style.width = `${state.originWidth}px`;
    dom.style.height = `${state.originHeight}px`;
  }
};
//压缩
const updateScale = () => {
  // 获取视口的真实尺寸
  const currentWidth = document.body.clientWidth;
  const currentHeight = document.body.clientHeight;
  // 获取大屏最终的宽高
  const realWidth: any = state.width || state.originWidth;
  const realHeight: any  = state.height || state.originHeight;
  // 缩放比例  = 分辨率宽高 / 传入宽高(可视宽高)
  const widthScale = currentWidth / realWidth;
  const heightScale = currentHeight / realHeight;
  // 如果dom存在,就按照比例缩放
  dom && (dom.style.transform = `scale(${widthScale}, ${heightScale})`);
};
// 重置缩放比例
const onResize = async () => {
  await initSize();
  updateScale();
};
const initMutationObserver = () => {
  // 监听元素属性变化
  const MutationObserver = window.MutationObserver;
  // 如果变化,就用onResize重置屏幕所缩放比例
  observer = new MutationObserver(onResize);
  observer.observe(dom, {
    attributes: true,
    attributeFilter: ['style'],
    attributeOldValue: true
  });
};
//移除监听属性
const removeMutationObserver = () => {
  if (observer) {
    observer.disconnect();
    observer.takeRecords();
    observer = null;
  }
};
onMounted(async () => {
  state.ready = false;
  await initSize();
  updateSize();
  updateScale();
  window.addEventListener('resize', debounce(100, onResize));
  initMutationObserver();
  state.ready = true;
});
onUnmounted(() => {
  window.removeEventListener('resize', onResize);
  removeMutationObserver();
});
</script>
<template>
  <div id="controlCabin-container" :ref="refName">
    <template v-if="state.ready">
      <slot></slot>
    </template>
  </div>
</template>

<style lang="less">
#controlCabin-container {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;
  /* overflow: hidden; */
  transform-origin: left top;
}
</style>
